package sanrenxing.dayEnd.backRepertoryTotal.controller;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import sanrenxing.dayEnd.backRepertoryTotal.domain.*;
import sanrenxing.dayEnd.backRepertoryTotal.service.*;
import sanrenxing.dayEnd.backRepertoryTotal.utils.ExclUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 功能:交易结算控制器类
 * 编写者：
 * 日期：2021
 * 版本：1.0
 */
@Controller
@RequestMapping("/trabsactionCrud")
public class TrabsactionController {
    //定义交易结算业务层接口
    @Autowired
    private TrabsactionBiz trabsactionBiz;
    //定义资金调拨业务层接口
    @Autowired
    private FundAllocationBiz fundAllocationBiz;
    //定义证券应收应付库存业务层接口
    @Autowired
    private SecRecAndPayStockBiz srapBiz;
    //定义证券应收应付业务层接口
    @Autowired
    private SecuritiesService securitiesService;

    //证券交易对象
    @Autowired
    private TransactionService transactionService;


    @GetMapping("/trabsaction")
    @ResponseBody
    public Map<String, Object> addTrabsaction(HttpServletRequest req, int page, int limit){
        /*定义用于多条件查询的TA交易处理对象*/
        TransactionSettlement transactionSettlement=new TransactionSettlement();
        /*接收来自请求中的交易方式*/
        String may=req.getParameter("may");
        if(may!=null && may.trim().length()!=0){
            transactionSettlement.setMay(may);
        }
        //接收来自请求中的结算日期
        String tranStatus=req.getParameter("tranStatus");
        if(tranStatus!=null && tranStatus.trim().length()!=0){
            transactionSettlement.setTranStatus(Integer.parseInt(tranStatus));
        }
        /*调用业务层获取查询条件方法*/
        String condition=trabsactionBiz.getCount(transactionSettlement);
        /*执行多条件分页查询的方法*/
        List<TransactionSettlementTwo> TATList=trabsactionBiz.findByPages(limit,page,condition);
        /*条件记录总行数*/
        int totalRows=trabsactionBiz.count(condition);

        /*定义映射集合对象*/
        Map<String,Object> map=new HashMap<>();
        map.put("code",0);
        map.put("msg","");
        map.put("data",TATList);
        map.put("count",totalRows);
        map.put("cashAccount",trabsactionBiz.queryCash());
        return map;
    }

    @DeleteMapping("/trabsaction/{tranId}")
    @ResponseBody
    public String delete(@PathVariable int tranId){
        return trabsactionBiz.delete(tranId)>0?"delete success":"delete failure";
    }

    /**
     * 点击结算时
     * @param tranId
     * @return
     */
    @PostMapping("/allocation/{tranId}")
    @ResponseBody
    public String account(@PathVariable String tranId){
        if (tranId.contains(",")) {
            //对交易数据编号字符串进行分割
            String[] strs = tranId.split(",");
            //循环查询
            for (String str : strs) {
                //调用业务层查询所有交易结算数据
                TransactionSettlement transaction=trabsactionBiz.findById(Integer.parseInt(str));
                //定义资金调拨对象
                FundAllocation fundAllocation=new FundAllocation();
                //定义证券应收应付库存对象
                SecRecAndPayStock srap=new SecRecAndPayStock();
                //定义证券应收应付对象
                ReceivableAndPayable receivableAndPayable=new ReceivableAndPayable();

                //判断交易结算状态，如果交易结算状态为未结算
                if(transaction.getTranStatus()==-1){
                    //定义一个变量，如果是卖出的债券则有值，否则为0
                    Double money=0.0;
                    //以下为添加证券应收应付
                    //添加证券应收应付的现金账户编号
                    receivableAndPayable.setCaId(String.valueOf(transaction.getCaId()));
                    //添加证券应收应付的证券信息编号
                    receivableAndPayable.setSeId(transaction.getSeId());
                    //添加证券应收应付的业务日期
                    receivableAndPayable.setBusinDate(transaction.getSettDate());
                    //取得证券编号判断是否为债券:如果该证券编号是债券并且为卖出
                    if (trabsactionBiz.ifIsBond(transaction.getSeId())!=0 && transaction.getMay().trim().equals("卖出")){
                        //那么它的卖出金额应该加上长久以来的债券利息，并且将证券应收应付的债券计息数据的金额减少(应为已经卖出很多支)
                        //通过 (债券每天利息(证券应收应付中取得)/债券总数量)*卖出数量=卖出债券每天所产生的利息*证券应收应付中该债券利息的数据条数(天数)=卖出债券所产生的利息
                        //通过债券编号，查询库存中该债券的数量，用于计算
                        int bondNum = trabsactionBiz.bondRepositoryCount(transaction.getSeId());
                        //通过债券编号，取得证券应收应付中的数据条数
                        int bondCount = trabsactionBiz.getBondCount(transaction.getSeId());
                        if (bondCount!=0){
                            //通过债券编号，取得证券应收应付中的每天利息
                            Double bondEveryMoney = trabsactionBiz.getBondEveryMoney(transaction.getSeId())/bondCount;
                            //通过算法计算卖出债券所收利息
                            money=((bondEveryMoney/bondNum)*transaction.getTranNum())*bondCount;
                            //添加证券应收应付金额
                            receivableAndPayable.setMoney(money+transaction.getSettMoney());
                            //将证券应收应付中对于该债券的每一行数据金额进行修改:修改为卖出债券后，卖出掉债券所产生的利息全部减掉：每条数据都要减
                            trabsactionBiz.updateBondEveryDayMoney((money/bondCount),transaction.getSeId());
                            //清除证券应收应付中类型为债券利息并且金额为0的数据，因为如果卖出所有债券的话，证券应收应付的数据也应该要删除
                            trabsactionBiz.clearBond();
                        }
                    }else{
                        //添加证券应收应付金额:取出交易结算的结算金额
                        receivableAndPayable.setMoney(transaction.getSettMoney());
                    }
                    //添加证券应收应付基金编号
                    receivableAndPayable.setFundId(transaction.getFundId());
                    //添加现金应收应付的统计状态:改为未统计
                    receivableAndPayable.setStates(0);


                    //设置资金调拨的基金编号
                    fundAllocation.setFundId(transaction.getFundId());
                    //设置资金调拨的现金账户编号
                    fundAllocation.setCaId(transaction.getCaId());
                    //根据交易方式判断
                    if(transaction.getMay().trim().equals("买入")){
                        //设置证券应收应付的业务类型为买入
                        receivableAndPayable.setBusinType("买入");
                        //设置证券应收应付的资金流向为流出
                        receivableAndPayable.setCapflow(-1);
                        //设置资金调拨方向为流出
                        fundAllocation.setDial(-1);
                        //设置资金调拨的调拨类型
                        fundAllocation.setReType("买入证券");
                    }else{
                        //设置证券应收应付的业务类型为卖出
                        receivableAndPayable.setBusinType("卖出");
                        //添加证券应收应付的资金流向为流入
                        receivableAndPayable.setCapflow(1);
                        //设置资金调拨方向为流入
                        fundAllocation.setDial(1);
                        //设置资金调拨的调拨类型
                        fundAllocation.setReType("卖出证券");
                    }
                    //调用添加证券应收应付的业务层添加方法
                    securitiesService.add(receivableAndPayable);
                    //设置资金调拨的调拨金额:在设置之前，如果是债券卖出，则金额通过计算以及算好了，判断money是否为null，不为null则为卖出证券
                    if (money!=null){
                        fundAllocation.setReMoney(money+transaction.getSettMoney());
                    }else fundAllocation.setReMoney(transaction.getSettMoney());
                    //判断买入还是卖出，如果是买入则当天资金调拨，如果是卖出则推迟调拨日期为T+1
                    if (transaction.getMay().trim().equals("买入")){
                        //设置资金调拨的调拨日期
                        fundAllocation.setReDate(transaction.getSettDate());
                    }else{//卖出
                        Calendar calendar= Calendar.getInstance();
                        calendar.setTime(transaction.getSettDate());
                        calendar.add(Calendar.DATE,1);
                        //设置资金调拨的调拨日期 T+1
                        fundAllocation.setReDate(calendar.getTime());
                    }
                    //设置资金调拨的业务日期
                    fundAllocation.setBusinDate(transaction.getSettDate());
                    //设置资金调拨的标记
                    fundAllocation.setMark("未处理");
                    //调用资金调拨的业务层添加方法
                    fundAllocationBiz.add(fundAllocation);

                    //设置证券应收应付库存的证券编号
                    srap.setSeId(transaction.getSeId());
                    //设置证券应收应付库存的基金编号
                    srap.setFundId(transaction.getFundId());
                    //设置证券应收应付库存的总金额
                    //srap.setSumMoney(transaction.getSettMoney());
                    //上面的代码是将结算金额算入证券应收应付库存的总金额，是不对的，因为总金额包括所有佣金，因此改为将成交金额算入，但是资金调拨和证券应收应付的总金额必须是结金额
                    srap.setSumMoney(transaction.getTranMoney());
                    //设置证券应收应付库存的证券数量
                    srap.setSecNum(transaction.getTranNum());
                    //设置证券应收应付库存的统计日期
                    srap.setDates(new SimpleDateFormat("yyyy-MM-dd").format(transaction.getSettDate()));
                    //设置证券应收应付库存的现金账户编号
                    srap.setCaId(transaction.getCaId());
                    //设置证券应收应付库存的业务类型为证券买卖
                    srap.setBusinType("证券买卖");
                    //判断交易方式
                    if(transaction.getMay().trim().equals("买入")){
                        //设置证券应收应付库存的业务状态为流出
                        srap.setBusinStat(-1);
                    }else{
                        //设置证券应收应付库存的业务状态为流入
                        srap.setBusinStat(1);
                    }
                    //调用证券应收应付库存业务层的添加方法
                    srapBiz.add(srap);

                    //将交易结算状态改为已结算
                    transaction.setTranStatus(1);
                    //调用交易结算业务层的修改方法
                    trabsactionBiz.update(transaction);
                }
            }
        }
        return "account success";
   }

    @RequestMapping("/form")
    public String form(HttpServletRequest request)throws Exception{
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;

        InputStream in =null;
        List<List<Object>> listob = null;
        MultipartFile file = multipartRequest.getFile("upfile");

        if(file.isEmpty()){
            throw new Exception("文件不存在！");
        }
        in = file.getInputStream();
        listob = new ExclUtils().getBankListByExcel(in,file.getOriginalFilename());
        in.close();

        SimpleDateFormat Sdf=new SimpleDateFormat("yyyy-MM-dd");
        //该处可调用service相应方法进行数据保存到数据库中，现只对数据输出
        for (int i = 0; i < listob.size(); i++) {
            List<Object> lo = listob.get(i);
            TransactionExcl transactionExcl = new TransactionExcl();
            transactionExcl.setTranId((int)Double.parseDouble(lo.get(0).toString()));
            transactionExcl.setTranDate(String.valueOf(lo.get(1)));
            transactionExcl.setTranNum((int)Double.parseDouble(lo.get(2).toString()));
            transactionExcl.setPrice(Double.valueOf(lo.get(3).toString()));
            transactionExcl.setSettMoney(Double.valueOf(lo.get(4).toString()));
            transactionExcl.setTranMoney(Double.valueOf(lo.get(5).toString()));
            transactionExcl.setSettDate(String.valueOf(lo.get(6)));
            transactionExcl.setFundId(String.valueOf(lo.get(7)));
            transactionExcl.setSeId(String.valueOf(lo.get(8)));
            transactionExcl.setStockId(String.valueOf(lo.get(9)));
            transactionExcl.setSeatId(String.valueOf(lo.get(10)));
            transactionExcl.setCaId((int)Double.parseDouble(lo.get(11).toString()));
            transactionExcl.setMay(String.valueOf(lo.get(12)));
            transactionExcl.setBreedRateId((int)Double.parseDouble(lo.get(13).toString()));
            transactionExcl.setTranStatus((int)Double.parseDouble(lo.get(14).toString()));
            transactionExcl.setActMoney((int)Double.parseDouble(lo.get(15).toString()));
            transactionExcl.setMark((int)Double.parseDouble(lo.get(16).toString()));
            transactionService.addExcl(transactionExcl);
        }
        return "redirect:/html/TransactionLXF.html";
    }

}
